Skip to main content
Version: 1.3.0

Auth API Documenationkadal auth

Login API Endpoint

  • Method: POST
  • Path: https://api.kadal.ai/aiwb/auth/api/v2/login

Description

Get Access token for User Account authentication.

Request

  • Content-Type: application/json

  • Payload

    The request body must be a JSON object with the following fields:

    FieldDescriptionTypeRequired
    usernameUsername of the accountstringYes
    passwordPassword for the accountstringYes
    tenant_codeShort code of the tenantstringNo

Response

  • Success (200 OK)
    {
    "status_code": 200,
    "message": "Login successful",
    "data": {
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUII6IjE1NTk5MDQxLWUyMmMtNGE5ZC1iZTc4LWNmZDFkODUzMc",
    "token_type": "Bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjZklBRE5feHhDSm1Wa1d5Ti1",
    "not-before-policy": 0,
    "session_state": "15599041-e22c-4a9d-be78-cfd1d8538559",
    "scope": "openid email profile",
    "first_name": "Abc",
    "last_name": "Def",
    "name": "Abc Def",
    "username": "abc.def",
    "user_id": "934e2e5e-4633-43c2-8b7a-87abcdf0fa5b",
    "roles": [
    {
    "role_id": "3b3c8da8-53b1-4ae9-a70b-12339ffd519c",
    "role_name": "Admin"
    }
    ],
    "email": "abc.def@mail.com",
    "platforms": [
    "AIWB",
    "CMS"
    ],
    "profile_pic_url": null,
    "tenant_id": "c3ea9217-f01e-4b70-9d95-9abc5f737810",
    "tenant_code": "T0001"
    }
    }

Usage

  • cURL Example
    curl -X POST "https://api.kadal.ai/aiwb/auth/api/v2/login" \
    -H "Content-Type: application/json" \
    -d '{
    "username": "your-username",
    "password": "your-password",
    "tenant_code": "tenant_code"
    }'
  • Python Example
    import requests

    url = "https://api.kadal.ai/aiwb/auth/api/v2/login"
    payload = {
    "username": "your-username",
    "password": "your-password",
    "tenant_code": "tenant_code"
    }

    response = requests.post(url, json=payload)
    token_data = response.json()
    access_token = token_data.get('access_token')

Token API Endpoint

  • Method: POST
  • Path: https://api.kadal.ai/auth/api/v1/oauth/connect/token

Description

Get Access token and Refresh token for Client Account authentication. This endpoint implements OAuth2 client credentials flow for service-to-service authentication.

Request

  • Content-Type: application/json

  • Payload

    The request body must be a JSON object with the following fields:

    FieldDescriptionTypeRequiredDefault
    realmRealm name for Tenant in Identity Provider (UUID format)stringOptional-
    client_idClient ID for Service AccessstringRequired-
    client_secretClient Secret Key for Service AccessstringRequired-
    grant_typeOAuth2 grant typestringOptionalclient_credentials
    scopesRequested scopes for the tokenstringOptionalopenid profile email roles

Response

  • Success (200 OK)
    {
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwiaFwTMHhbqSXtiNkvUlcp0pMdDYy6nZ6E8-2Lg",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAMF31HZzy865t7DabmSpX03T4UZO-TTvvh5B4QyG1so",
    "token_type": "Bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjZklBRE5feHhDSiOi",
    "not-before-policy": 0,
    "session_state": "5225b959-0507-4b32-98fb-76aec1110ad8",
    "scope": "email profile"
    }

Implementation Details

  • Flow Description
    1. Client Validation: The service validates the provided client_id and client_secret
    2. Realm Resolution: If no realm is provided, the service looks up the client's associated realm
    3. Token Generation: Keycloak generates access and refresh tokens
    4. CloudFront Integration: The service generates CloudFront cookies for CDN access
    5. Response: Returns tokens with appropriate HTTP cookies set
  • Additional Features
    • CloudFront Cookie Integration: Automatically sets CloudFront cookies for CDN access
    • Token Caching: Tokens are cached for performance optimization
    • Audit Logging: All token generation events are logged for security auditing

Usage

  • cURL Example
    curl -X POST "https://api.kadal.ai/auth/api/v1/oauth/connect/token" \
    -H "Content-Type: application/json" \
    -d '{
    "client_id": "your-client-id",
    "client_secret": "your-client-secret",
    "grant_type": "client_credentials",
    "scopes": "openid profile email roles"
    }'
  • Python Example
    import requests

    url = "https://api.kadal.ai/auth/api/v1/oauth/connect/token"
    payload = {
    "client_id": "your-client-id",
    "client_secret": "your-client-secret",
    "grant_type": "client_credentials",
    "scopes": "openid profile email roles"
    }

    response = requests.post(url, json=payload)
    token_data = response.json()
    access_token = token_data.get('access_token')

Introspect API Endpoint

  • Method: POST
  • Path: https://api.kadal.ai/aiwb/auth/api/v2/introspect-token

Description

Validate Access Token and retrieve its metadata. This endpoint allows clients to determine the active state of an OAuth 2.0 token and obtain meta-information about the token.

Request

  • Content-Type: application/json

  • Query Parameters
    ParameterDescriptionTypeRequired
    tokenThe OAuth2 access token to be introspectedstringYes

Response

  • Success Response (200 OK) - Active Token Response

    {
    "exp": 1756459124,
    "iat": 1756455524,
    "jti": "8c131e0e-4507-41d9-a446-ad3bd1d3bbea",
    "iss": "https://keycloak.kadal.ai/realms/106a2856-892e-41ac-8fe4-00976a8aaec9",
    "sub": "f:34a7ab92-baa1-4ab5-a27f-933abaa71a25:cca9fa8e-6aba-11f0-8bbc-0666121337bd",
    "typ": "Bearer",
    "azp": "1f7a6f4d-1c3f-4717-b829-b938202897be",
    "session_state": "dbf0c3b4-a017-4e3f-b1be-e14bda37dfa7",
    "name": "Abc Def",
    "email": "abc.def@learningmate.com",
    "email_verified": false,
    "allowed-origins": [
    "/*"
    ],
    "scope": "openid profile email",
    "sid": "dbf0c3b4-a017-4e3f-b1be-e14bda37dfa7",
    "tenant_id": "106a2856-892e-41ac-8fe4-00976a8aaec9",
    "user_id": "cca9fa8e-6bab-11f0-8xyz-0666121337bd",
    "last_name": "Def",
    "tenant_short_code": "14UT7",
    "user_roles": [
    {
    "role_name": "Repository Manager",
    "role_id": "fdcef60d-841e-43a3-baa9-b6ac2010acc7"
    }
    ],
    "first_name": "Abc",
    "istenantadmin": false,
    "username": "abc.def@learningmate.com",
    "client_id": "1f7a6f4d-1c3f-4717-b829-b938202897be",
    "active": true,
    "expires_in": 3600
    }
  • Other Responses

    • 401: Inactive token response

Implementation Details

  • Flow Description
    1. Token Extraction: Extract the token from request parameters
    2. Client Resolution: Look up client credentials based on the provided token
    3. Authorization Setup: Create Basic auth header using resolved client credentials
    4. Token Introspection: Call Keycloak's introspection endpoint
    5. Response Validation: Check if token is active
    6. Response: Return introspection metadata or error
  • Token Validation Process
    • The service maintains a cache/database mapping between tokens and their associated clients
    • Client credentials are automatically resolved to authenticate with Keycloak
    • Keycloak performs the actual token validation and returns metadata
    • The service validates the active field before returning the response
  • Security Features
    • Automatic Client Resolution: No need to provide client credentials if token is in cache
    • Realm Isolation: Tokens are validated within their respective realms
    • Audit Logging: All introspection requests are logged for security monitoring

Usage

  • cURL Example
    curl -X POST "https://api.kadal.ai/aiwb/auth/api/v2/introspect-token?token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldU..."
  • Python Example
    import requests

    url = "https://api.kadal.ai/aiwb/auth/api/v2/introspect-token"
    token = "YOUR_TOKEN"

    params = {
    "token": token
    }

    response = requests.post(url, params=params)

    if response.status_code == 200:
    result = response.json()
    if result.get('active') == True:
    print(f"Token expires at: {result['exp']}")
    print(f"Scopes: {result['scope']}")
    else:
    print("Token is inactive")
    else:
    print(f"Error: {response.status_code} - {response.text}")